/**
 * Created by meiguizhinian on 2018/7/18
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Array
(function () {
	/**
	 * @compare 比较函数返回true/false
	 * */
	LLArray = function (compare=null) {
		//成员变量
		this._compare = compare;
		this._array = [];
	};
	let p = LLArray.prototype;

	p.empty = function () {
		return this._array.length === 0;
	};
	p.clear = function () {
		this._array = [];
	};
	p.size = function () {
		return this._array.length;
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	p.get = function(idx) {
		if (idx>=0 && idx<this._array.length) {
			return this._array[idx];
		}
		return undefined;
	};
	p.set = function(idx, value) {
		this._array[idx] = value;
	};

	p.insert = function(idx, ...value) {
		if (idx>=0 && idx<=this._array.length) {
			this._array.splice(idx, 0, ...value)
		}
	};
	////////////////////////////////////////////////////////////////////////////back
	p.back = function () {
		if (!this.empty()) {
			return this._array[this._array.length-1];
		}
		return undefined;
	};
	p.push_back = function (...value) {
		return this._array.push(...value);
	};
	p.pop_back = function () {
		return this._array.pop();
	};

	p.push = p.push_back;
	p.pop = p.pop_back;
	////////////////////////////////////////////////////////////////////////////front
	p.front = function () {
		if (!this.empty()) {
			return this._array[0];
		}
		return undefined;
	};
	p.push_front = function (...value) {
		this._array.unshift(...value)
	};
	p.pop_front = function () {
		return this._array.shift();//splice(0, 1)
	};

	p.unshift = p.push_front;
	p.shift = p.pop_front;
})();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Dictionary
(function () {
	/**
	 * @compare 比较函数返回true/false
	 * */
	LLDictionary = function (compareKey=null,compareValue=null) {
		//成员变量
		this._compareKey = compareKey;
		this._compareValue = compareValue;
		this._map = new Map();
	};
	let p = LLDictionary.prototype;

	p.empty = function () {
		return this._map.size === 0;
	};
	p.clear = function () {
		this._map.clear();
	};
	p.size = function () {
		return this._map.size;
	};
	p.assign = function(other) {
		Object.assign(this, other);
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	p.get = function(key) {
		key = this.key(key);
		if (key !== undefined) {
			return this._map.get(key);
		}
		return undefined;
	};

	p.set = function (key, value) {
		let key_ = this.key(key);
		if (key_ === undefined) {
			key_ = key;
		}
		this._map.set(key_, value);
	};
	/**
	 * @param key
	 * @return {Boolean} true:有键值可以删除，false：没有找到要删除的键值
	 * */
	p.erase = function(key) {
		let key_ = this.key(key);
		if (key_ !== undefined) {
			this._map.delete(key_);
			return true;
		}
		return false;
	};
	p.delete = p.erase;

	p.has = function(key) {
		return this.key(key) !== undefined;
	};
	p.contains = function(value) {
		return this.value(value) !== undefined;
	};

	p.forEach = function(callbackfn) {
		this._map.forEach(callbackfn);
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	p.key = function (key) {
		if (this.empty()) {
			return undefined;
		}
		if (this._compareKey) {
			for (let [k,v] of this._map) {
				if (this._compareKey(k, key)) {
					return k;
				}
			}
		} else {
			if (this._map.has(key)) {
				return key;
			}
			//浮点数做为索引,由于误差导致会出现找不到问题
			if (typeof key === 'number' || Object.prototype.toString.call(key) === '[object Number]') {
				if (parseInt(key)!==key) {
					for (let [k,v] of this._map) {
						if (Math.abs(k-key)<=Number.EPSILON) {
							return k;
						}
					}
				}
			}
		}
		//cc.log("not find key",key);
		return undefined;
	};
	p.value = function (value) {
		if (this.empty()) {
			return null;
		}
		if (this._compareValue) {
			for (let [k,v] of this._map) {
				if (this._compareValue(v, value)) {
					return v;
				}
			}
		} else {
			for (let [k,v] of this._map) {
				if (v === value) {
					return v;
				}
			}
			//浮点数做为索引直接使用[],由于误差导致会出现找不到问题
			if (typeof value === 'number' || Object.prototype.toString.call(key) === '[object Number]') {
				if (parseInt(value)!==value) {
					for (let [k,v] of this._map) {
						if (Math.abs(v-value)<=Number.EPSILON) {
							return v;
						}
					}
				}
			}
		}
		//cc.log("not find value");
		return undefined;
	};

	p.allKeys = function() {
		let keys = [];
		for (let k of this._map.keys()) {
			keys.push(k);
		}
		return keys;
	};
	p.allValues = function() {
		let keys = [];
		for (let v of this._map.values()) {
			keys.push(v);
		}
		return keys;
	};
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////支持迭代器
	p.entries = function*() {
		for (let item of this._map) {
			yield item;
		}
		//return this[Symbol.iterator]();
	};
	p.keys = function*() {
		for (let [key, value] of this._map) {
			yield key;
		}
	};
	p.values = function*() {
		for (let [key, value] of this._map) {
			yield value;
		}
	};
	if (!cc.sys.isNative) {
		p[Symbol.iterator] = function*() {
			for (let item of this._map) {
				yield item;
			}
		};
	}
})();
